/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package com.vng.zing.zprofilemiddleware.model;

import com.vng.zing.configer.ZConfig;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import org.apache.log4j.Logger;

/**
 *
 * @author namhh
 */
public class ZProfileMySqlConnection {
    private static final Logger _logger = Logger.getLogger(ZProfileMySqlConnection.class);
    private static final ZConfig config =  ZConfig.Instance;
    private final String _host;
    private final int _port;
    private final String _dbname;
    private final String _user;
    private final String _password;
    private BlockingQueue<Connection> pool;
    private String url;
    public static ZProfileMySqlConnection _instance;

    private ZProfileMySqlConnection() {
        _host = config.getString("mysql.host","localhost");
        _port = config.getInt("mysql.port",3306);
        _dbname = config.getString("mysql.db", "ZProfile") ;
        _user = config.getString("mysql.username", "root") ;
        _password = config.getString("mysql.password", "root") ;
        this.init(10);
    }

    private boolean init(int poolsize) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            url = "jdbc:mysql://" + _host + ":" + _port + "/" + _dbname + "?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&interactiveClient=true&" + "&user=" + _user
                    + "&password=" + _password;

            BlockingQueue<Connection> cnnPool = new ArrayBlockingQueue<Connection>(poolsize);
            while (cnnPool.size() < poolsize) {
                cnnPool.add(DriverManager.getConnection(url));
            }
            pool = cnnPool;
        } catch (Exception ex) {
            _logger.error(ex.getMessage() + ex);
            return false;
        }
        return true;
    }

    public static synchronized ZProfileMySqlConnection getInstance() {
        return (_instance == null) ? _instance = new ZProfileMySqlConnection() : _instance;
    }

    public Connection getDbConnection() {
        Connection conn = null;
        int retry = 0;
        do {
            try {
                conn = pool.take();
                if (conn == null || !conn.isValid(0)) {
                    conn = DriverManager.getConnection(url);
                }
            } catch (Exception ex) {
                _logger.warn(ex);
            }
            ++retry;
        } while (conn == null && retry < 3);
        return conn;
    }

    public void releaseDbConnection(java.sql.Connection conn) {
        if (conn != null) {
            pool.add(conn);
        }

    }
}
